/**
 * 
 */
package org.vsg.stock.basic.persistence.mybatis;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.vsg.stock.basic.domain.BalanceLine;
import org.vsg.stock.basic.domain.BalanceLineKeyPoint;
import org.vsg.stock.basic.domain.mybatis.BalanceLineProxy;
import org.vsg.stock.basic.persistence.BalanceLineDao;
import org.vsg.stock.basic.service.StockBusinessHelper;

/**
 * @author Bill Vison
 *
 */
public class BalanceLineDaoImpl extends SqlSessionDaoSupport implements BalanceLineDao {

	private static final Logger logger = LoggerFactory.getLogger(BalanceLineDaoImpl.class);
		
	
	@Override
	public void save(BalanceLine balanceLine) throws DataAccessException {

		// --- copy bean ---
		BeanUtilsBean beanUtilsBeanInst = BeanUtilsBean.getInstance();
		
		BalanceLineProxy destProxy = new BalanceLineProxy();
		
		try {
			
			beanUtilsBeanInst.copyProperties(destProxy, balanceLine);

			String statement = "org.vsg.stock.basic.domain.mybatis.BalanceLineProxy." +
			"insertBalanceLine";

			int result = this.getSqlSessionTemplate().insert(statement, balanceLine);
			
			if (logger.isDebugEnabled() ) {
				if (result != 0) {
					logger.debug("Insert Balance line data success! ");
				}
			}
			
			// --- update all save key point ---
			destProxy.setSqlSessionTemplate( getSqlSessionTemplate() );
			destProxy.insertKeyPoints();
		
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}


	@Override
	public Map<BalanceLineKeyPoint, Set<String>> findAndByOrgBalaline(List<BalanceLine> balaLines)
			throws DataAccessException {
		String statement = "org.vsg.stock.basic.domain.mybatis.BalanceLineProxy.findExistedBalanineByPoint";
		
		List<BalanceLine> balaLine = new Vector<BalanceLine>();
		
		BalanceLine line = null;
		
		Set<BalanceLineKeyPoint> pointFindExist = new HashSet<BalanceLineKeyPoint>();
		
		Map<BalanceLineKeyPoint , Set<String> > pointToLines = new HashMap<BalanceLineKeyPoint , Set<String> >();
		
		for (Iterator<BalanceLine> lineIter = balaLines.iterator() ; lineIter.hasNext(); ) {
			line = lineIter.next();
			// --- search all key points ---
			for (Iterator<BalanceLineKeyPoint> keyPointIter = line.getKeyPoints().iterator() ; keyPointIter.hasNext(); ) {
				BalanceLineKeyPoint keyPoint = keyPointIter.next();
				
				if (pointFindExist.contains(  keyPoint )) {
					continue;
				}

				Map<String,Object> params = new HashMap<String,Object>();
				params.put("priceType", keyPoint.getPriceType());
				params.put("stockCode", line.getStockCode());
				params.put("form", line.getForm());
				// --- set the price during ---
				double maxPrice = StockBusinessHelper.getDiffRelativedPrice( keyPoint.getPrice() , StockBusinessHelper.MAX_DIFF);
				double minPrice = StockBusinessHelper.getDiffRelativedPrice( keyPoint.getPrice() , StockBusinessHelper.MIN_DIFF);
				
				params.put("maxPrice", maxPrice);
				params.put( "minPrice"  , minPrice);

				List<Map>  existedLineList = this.getSqlSessionTemplate().selectList(statement , params);
				
				Set<String> lineIds = new HashSet<String>();
				
				for (Map entry : existedLineList) {
					
					double price = new Double( entry.get("price").toString() );
					//Date refDate = (Date)entry.get("ref_date");
					String lineId =(String) entry.get("line_id");
					//String form = (String)entry.get("form");
					
					lineIds.add( lineId );
					
				}
				pointFindExist.add( keyPoint );				
				pointToLines.put( keyPoint , lineIds);
				
			}
		}
		return pointToLines;
	}
	
	
}
